//	NAME:			mcPoint.h

#ifndef _MC_POINTS_H_
#define _MC_POINTS_H_

#include <stdio.h>
#include <fstream>

using namespace std;

class McPoint
{
public:

	~McPoint() {};
	virtual double Distance(const McPoint& p) const = 0;
	virtual double Azimuth(const McPoint& p) const = 0;
	virtual double X() const = 0;
	virtual double Y() const = 0;
	virtual double Z() const = 0;
	virtual double GetX() const = 0;
	virtual double GetY() const = 0;
	virtual double GetZ() const = 0;


	virtual double& rX() = 0;
	virtual double& rY() = 0;
	virtual double& rZ() = 0;
	virtual void SetX(const double x) = 0;
	virtual void SetY(const double y) = 0;
	virtual void SetZ(const double z) = 0;

	virtual void Set(const double x, const double y, const double z) = 0;
};


struct LPoint
{
	int Row, Col;
};


class McPoint2D :
	public McPoint
{
public:
	McPoint2D(void);
	~McPoint2D(void);
	McPoint2D(double x1, double y1);
	McPoint2D(const McPoint &p);

	McPoint2D operator+(const McPoint2D& p);
	McPoint2D operator-(const McPoint2D& p);
	McPoint2D operator+=(const McPoint2D& p);
	McPoint2D operator-=(const McPoint2D& p);
	McPoint2D& operator=(const McPoint& p);
	McPoint2D operator*(const double scale);
	McPoint2D operator/(const double scale);
	bool operator==(const McPoint2D& p);

	friend ofstream & operator>>(McPoint2D &p, ofstream &strm);
	friend ifstream & operator<<(McPoint2D &p, ifstream &strm);

	double Distance(const McPoint& p) const;
	double Azimuth(const McPoint& p) const;

	double X() const;
	double Y() const;

	double GetX() const;
	double GetY() const;

	void SetX(const double x);
	void SetY(const double y);

	double& rX();
	double& rY();

	void Get(double& x1, double& y1) const;

	void Set(const double x1, const double y1);
	void Set(const double x, const double y, const double z);

private:
	double Z() const { return 0.0; };

	double GetZ() const { return 0.0; };

	double& rZ() { return x; };

	void SetZ(const double z) {};



public:
	double x;
	double y;
};


class McPoint3D :
	public McPoint2D
{
public:
	McPoint3D(void);
	~McPoint3D(void);

	McPoint3D(double x1, double y1, double z1);
	McPoint3D(const McPoint& p);

	// OPERATORS

	McPoint3D operator+(const McPoint3D& p);
	McPoint3D operator-(const McPoint3D& p);
	McPoint3D operator*(const double scale);
	McPoint3D& operator=(const McPoint3D& p);
	bool operator==(const McPoint3D& p);

	// OPERATIONS
	void Scale(const double scale);
	double Distance(const McPoint& p) const;

	void SetZ(const double z1);
	void Set(const double x1, const double y1, const double z1);
	void Get(double& x1, double& y1, double& z1) const;

	// ACCESS
	double Z() const;
	double GetZ() const;
	double & rZ();

	// INQUIRY

public:
	double z;
};


class McImagePoint
{

public:

	// LIFECYCLE
	McImagePoint();
	McImagePoint(const int x1, const int y1);

	// OPERATORS
	McImagePoint	operator+(const McImagePoint& p) const;
	McImagePoint	operator-(const McImagePoint& p) const;
	McImagePoint&	operator=(const McImagePoint& p);
	bool			operator==(const McImagePoint& p) const;
	virtual	ofstream &		operator>>(ofstream &strm);
	virtual	ifstream &		operator<<(ifstream &strm);
	//	ofstream &       operator>>(ofstream &strm, McImagePoint &im);
	//	ifstream &       operator<<(ifstream &strm, McImagePoint &im);  

	// ACCESS
	inline	int	X(void) const { return x; };
	inline	int	Y(void) const { return y; };
	inline	void	SetX(const int x1){ x = x1; };
	inline  void	SetY(const int y1){ y = y1; };
	inline	int	Row(void) const { return x; };
	inline	int	Col(void) const { return y; };
	inline  void	SetRow(const int row1){ x = row1; };
	inline	void	SetCol(const int col1){ y = col1; };
	virtual void	Set(const McPoint2D pt);

protected:
	int	x;
	int	y;
};

#endif
